package cn.mill.common.data;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Comparator;

public class ItemArray implements Serializable {
	
	private static final long serialVersionUID = 7627800210928355822L;
	
	private int size = 0;
	
	private Item[] items;
	
	public ItemArray() {
		this.init(0);
	}
	
	public ItemArray(int size) {
		items = new Item[size];
	}
	
	public void init(int size) {
		items = new Item[size];
	}
	
	public void addItem(Item item) {
		this.addItem(item, getSize());
	}
	
	public void addItem(Item item, int pos) {
		if (this.items == null || this.items.length <= pos) {
			Item[] newArray = new Item[pos + 1];
			int length = this.items == null ? 0 : this.size;
			System.arraycopy(items, 0, newArray, 0, length);
			items = newArray;
		}
		this.items[pos] = item;
		this.size++;
	}
	
	public void merge(ItemArray itemArray) {
		if (itemArray != null && itemArray.getItems() != null && itemArray.getItems().length > 0) {
			Item[] two = itemArray.getItems();
			Item[] newArray = new Item[this.items.length + two.length];
			System.arraycopy(items, 0, newArray, 0, this.size);
			System.arraycopy(two, 0, newArray, this.size, itemArray.getSize());
			this.items = newArray;
			this.setSize(this.getSize() + itemArray.getSize());
		}
	}
	
	public Item search(String name, String synonym) {
		int index = -1;
		if (synonym != null && !synonym.isEmpty()) {
			name = name + "," + synonym;
			String[] ns = name.split(",");
			for (String s : ns) {
				index = this.binarySearch(s);
				if (index >= 0 && index < this.items.length) {
					return this.items[index];
				}
			}
		} else {
			index = this.binarySearch(name);
		}
		if (index >= 0 && index < this.items.length) {
			return this.items[index];
		} else {
			return null;
		}
	}
	
	public void sort() {
		Arrays.sort(this.items, new Comparator<Item>() {
			@Override
			public int compare(Item o1, Item o2) {
				if (o1 != null && o2 != null) {
					return o1.getName().compareTo(o2.getName());
				} else {
					return 0;
				}
			}
		});
		// 排序后删除 末尾 空值,因为 当初数组初始化的时候，可能空间申请多了。然后末尾就会有没有使用的空间。
		if (this.items != null) {
			int i = this.items.length;
			do {
				i--;
			} while (i >= 0 && this.items[i] == null);
			if (i >= 0 && i < this.items.length) {
				Item[] newArray = new Item[i + 1];
				System.arraycopy(items, 0, newArray, 0, i + 1);
				this.items = newArray;
				this.size = i + 1;
			} else {
				this.items = new Item[0];
				this.size = 0;
			}
		}
	}
	
	/*
	 * 二分查找也称折半查找（Binary
	 * Search），它是一种效率较高的查找方法。但是，折半查找要求线性表必须采用顺序存储结构，而且表中元素按关键字有序排列。
	 * 所以 数组要按照 那么排序。
	 */
	public int binarySearch(String name) {
		if (this.items == null) {
			return 0;
		} else {
			int high = this.items.length - 1;
			if (this.items.length < 1) {
				return high;
			}
			int low = 0;
			while (low <= high) {
				int mid = (low + high) >>> 1;
				int cmp = this.items[mid].getName().compareTo(name);
				if (cmp < 0) {
					low = mid + 1;
				} else if (cmp > 0) {
					high = mid - 1;
				} else {
					return mid;
				}
			}
			return -(low + 1);
		}
	}
	
	/*******************************************************************************************************/
	public int getSize() {
		return size;
	}
	
	public void setSize(int size) {
		this.size = size;
	}
	
	public Item[] getItems() {
		return items;
	}
	
	public void setItems(Item[] items) {
		this.items = items;
	}
}
